import { TypeSchema, TypeSchemaType, ProtocolError } from './protocol';

function parseType(input: string): [TypeSchema, string] {
  input = input.trim();
  
  // 存储所有可能的解析结果
  const possibleResults: Array<[TypeSchema, string]> = [];
  
  // 基本类型
  if (/^Void/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Void), input.slice(4)]);
  if (/^Int/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Int), input.slice(3)]);
  if (/^Float/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Float), input.slice(5)]);
  if (/^Str/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Str), input.slice(3)]);
  if (/^String/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Str), input.slice(6)]);
  if (/^Bool/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Bool), input.slice(4)]);
  if (/^Json/i.test(input)) possibleResults.push([new TypeSchema(TypeSchemaType.Json), input.slice(4)]);
  
  // List类型
  if (/^\[/.test(input)) {
    try {
      const [elementType, rest] = parseType(input.slice(1));
      if (rest.startsWith(']')) {
        possibleResults.push([new TypeSchema(TypeSchemaType.List, elementType), rest.slice(1)]);
      }
    } catch (e) {}
  }
  
  // List<T>类型
  if (/^List</i.test(input)) {
    try {
      const [elementType, rest] = parseType(input.slice(5));
      if (rest.startsWith('>')) {
        possibleResults.push([new TypeSchema(TypeSchemaType.List, elementType), rest.slice(1)]);
      }
    } catch (e) {}
  }
  
  // Map类型
  if (/^\{/.test(input)) {
    try {
      const [keyType, rest1] = parseType(input.slice(1));
      if (rest1.startsWith(',')) {
        const [valueType, rest2] = parseType(rest1.slice(1));
        if (rest2.startsWith('}')) {
          possibleResults.push([new TypeSchema(TypeSchemaType.Map, undefined, keyType, valueType), rest2.slice(1)]);
        }
      }
    } catch (e) {}
  }
  
  // Map<K,V>类型
  if (/^Map</i.test(input)) {
    try {
      const [keyType, rest1] = parseType(input.slice(4));
      if (rest1.startsWith(',')) {
        const [valueType, rest2] = parseType(rest1.slice(1));
        if (rest2.startsWith('>')) {
          possibleResults.push([new TypeSchema(TypeSchemaType.Map, undefined, keyType, valueType), rest2.slice(1)]);
        }
      }
    } catch (e) {}
  }
  
  // Tuple类型
  if (/^\(/.test(input)) {
    try {
      const elements: TypeSchema[] = [];
      let rest = input.slice(1);
      if (!rest.startsWith(')')) {
        while (true) {
          const [element, newRest] = parseType(rest);
          elements.push(element);
          rest = newRest;
          if (rest.startsWith(')')) break;
          if (!rest.startsWith(',')) throw new ProtocolError(`无效的Tuple类型: ${input}`);
          rest = rest.slice(1);
        }
      }
      if (elements.length >= 2) {
        possibleResults.push([new TypeSchema(TypeSchemaType.Tuple, undefined, undefined, undefined, elements), rest.slice(1)]);
      }
    } catch (e) {}
  }
  
  // Optional类型
  if (/^\?/.test(input)) {
    try {
      const [elementType, rest] = parseType(input.slice(1));
      possibleResults.push([new TypeSchema(TypeSchemaType.Opt, elementType), rest]);
    } catch (e) {}
  }
  
  if (/^Option</i.test(input)) {
    try {
      const [elementType, rest] = parseType(input.slice(7));
      if (rest.startsWith('>')) {
        possibleResults.push([new TypeSchema(TypeSchemaType.Opt, elementType), rest.slice(1)]);
      }
    } catch (e) {}
  }
  
  // 自定义类型
  const match = input.match(/^[a-zA-Z][a-zA-Z0-9_]*/);
  if (match) {
    const typeName = match[0];
    if (!['List', 'Map', 'Option', 'Tuple'].includes(typeName)) {
      possibleResults.push([new TypeSchema(TypeSchemaType.DataType, undefined, undefined, undefined, undefined, typeName), input.slice(typeName.length)]);
    }
  }
  
  // 选择最长的匹配结果
  // if (possibleResults.length > 0) {
  //   possibleResults.sort((a, b) => {
  //     const aConsumed = input.length - a[1].length;
  //     const bConsumed = input.length - b[1].length;
  //     return bConsumed - aConsumed;
  //   });
  //   return possibleResults[0];
  // }
  let minRestLength = Infinity;
  let result = null;
  for (const r of possibleResults) {
    if (r[1].length < minRestLength) {
      minRestLength = r[1].length;
      result = r;
    }
  }
  if (result) {
    return result;
  }
  throw new ProtocolError(`无法解析的类型: ${input}`);
}

export function parse_abs_type(input_str: string): TypeSchema {
  if (!input_str || !input_str.trim()) {
    throw new ProtocolError('类型字符串不能为空');
  }
  try {
    const [type, rest] = parseType(input_str.trim());
    if (rest.trim()) {
      throw new ProtocolError(`类型字符串包含未解析的内容: ${rest}`);
    }
    return type;
  } catch (error) {
    if (error instanceof ProtocolError) {
      throw error;
    }
    throw new ProtocolError(`类型解析错误 '${input_str}': ${error instanceof Error ? error.message : String(error)}`);
  }
}

export function task_nominal_to_symbolic(task: string): [string, TypeSchema, TypeSchema] {
  if (!task || !task.trim()) {
    throw new ProtocolError('任务签名不能为空');
  }
  const splits = task.split(':');
  if (splits.length !== 2) {
    throw new ProtocolError(`任务签名不能正确分割冒号: ${task}`);
  }
  const [name, type_sig] = splits;
  const trimmed = name.trim();
  if (!trimmed) {
    throw new ProtocolError(`任务名称不能为空: ${task}`);
  }
  const type_splits = type_sig.split('->');
  if (type_splits.length !== 2) {
    throw new ProtocolError(`任务签名不能正确分割箭头: ${task}`);
  }
  const [input_type_str, output_type_str] = type_splits;
  try {
    const input_type = parse_abs_type(input_type_str.trim());
    const output_type = parse_abs_type(output_type_str.trim());
    return [trimmed, input_type, output_type];
  } catch (e) {
    if (e instanceof ProtocolError) {
      throw new ProtocolError(`任务类型解析错误: ${task}\n原因: ${e.message}`);
    }
    throw e;
  }
}